package requirejs;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.intellij.lang.ASTNode;
import com.intellij.lang.javascript.JSElementTypes;
import com.intellij.lang.javascript.JSTokenTypes;
import com.intellij.lang.javascript.psi.impl.JSFileImpl;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.xml.XmlFileImpl;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import requirejs.settings.Settings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class RequirejsProjectComponent implements ProjectComponent {
protected Project project;
protected Settings settings;
protected boolean settingValidStatus;
protected String settingValidVersion;
protected String settingVersionLastShowNotification;
protected final Logger LOG = Logger.getInstance("Requirejs-Plugin");
protected String requirejsBaseUrl;
protected RequirePaths requirePaths;
protected RequireMap requireMap = new RequireMap();
private RequireConfigVfsListener vfsListener;
public PackageConfig packageConfig;
public RequirejsProjectComponent(Project project) {
this.project = project;
settings = Settings.getInstance(project);
requirePaths = new RequirePaths(this);
packageConfig = new PackageConfig(this);
}
@Override
public void projectOpened() {
if (isEnabled()) {
validateSettings();
}
}
public void watchConfigFile() {
// Add the Virtual File listener
vfsListener = new RequireConfigVfsListener();
VirtualFileManager.getInstance().addVirtualFileListener(vfsListener, project);
}
public void stopWatchConfigFile() {
if (vfsListener == null) {
return;
}
VirtualFileManager.getInstance().removeVirtualFileListener(vfsListener);
}
@Override
public void projectClosed() {
}
@Override
public void initComponent() {
if (isEnabled()) {
validateSettings();
}
}
@Override
public void disposeComponent() {
}
@NotNull
@Override
public String getComponentName() {
return "RequirejsProjectComponent";
}
public Logger getLogger() {
return LOG;
}
public boolean isEnabled() {
return Settings.getInstance(project).pluginEnabled;
}
public boolean isSettingsValid() {
if (!settings.getVersion().equals(settingValidVersion)) {
validateSettings();
settingValidVersion = settings.getVersion();
}
return settingValidStatus;
}
public boolean validateSettings() {
if (null == getWebDir()) {
showErrorConfigNotification(
"Public directory not found. Path " +
getContentRoot().getPath() + '/' + settings.publicPath +
" not found in project"
);
LOG.debug("Public directory not found");
settingValidStatus = false;
return false;
}
if (isEnabled()) {
watchConfigFile();
} else {
stopWatchConfigFile();
}
settingValidStatus = true;
return true;
}
public void clearParse() {
requirejsBaseUrl = null;
requirePaths.clear();
requireMap.clear();
packageConfig.clear();
}
protected void showErrorConfigNotification(String content) {
if (!settings.getVersion().equals(settingVersionLastShowNotification)) {
settingVersionLastShowNotification = settings.getVersion();
showInfoNotification(content, NotificationType.ERROR);
}
}
public VirtualFile getWebDir(VirtualFile elementFile) {
if (null != elementFile) {
if (settings.publicPath.isEmpty()) {
return getContentRoot(elementFile);
}
}
VirtualFile vfWebDir = findPathInContentRoot(settings.publicPath);
if (null != vfWebDir) {
return vfWebDir;
} else {
return null;
}
}
public VirtualFile getWebDir() {
return getWebDir(null);
}
protected VirtualFile findPathInWebDir(String path) {
if (settings.publicPath.isEmpty()) {
return findPathInContentRoot(path);
}
VirtualFile vfWebDir = getWebDir();
if (null != vfWebDir) {
return vfWebDir.findFileByRelativePath(path);
} else {
return null;
}
}
public VirtualFile getContentRoot() {
VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots();
if (contentRoots.length > 0) {
return contentRoots[0];
} else {
return project.getBaseDir();
}
}
public VirtualFile getContentRoot(VirtualFile file) {
return ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(file);
}
protected VirtualFile findPathInContentRoot(String path) {
VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots();
if (contentRoots.length > 0) {
for(VirtualFile contentRoot : contentRoots) {
VirtualFile vfPath = contentRoot.findFileByRelativePath(path);
if (null != vfPath) {
return vfPath;
}
}
return null;
} else {
return project.getBaseDir().findFileByRelativePath(path);
}
}
public void showInfoNotification(String content, NotificationType type) {
Notification errorNotification = new Notification("Require.js plugin", "Require.js plugin", content, type);
Notifications.Bus.notify(errorNotification, this.project);
}
public List<String> getModulesNames() {
List<String> modules = new ArrayList<String>();
if (requirePaths.isEmpty()) {
if (!parseRequirejsConfig()) {
return modules;
}
}
modules.addAll(requirePaths.getAliasToFiles());
Collection<Package> filteredPackages = Collections2.filter(packageConfig.packages, new Predicate<Package>() {
@Override
public boolean apply(Package aPackage) {
return aPackage != null && aPackage.mainExists;
}
});
Collection<String> ret = Collections2.transform(filteredPackages, new Function<Package, String>() {
@Override
public String apply(Package aPackage) {
return aPackage.name;
}
});
modules.addAll(ret);
return modules;
}
public String getBaseUrl() {
if (null == requirejsBaseUrl) {
VirtualFile baseUrlPath = getBaseUrlPath(true);
if (null != baseUrlPath) {
requirejsBaseUrl = baseUrlPath.getPath().replace(getWebDir().getPath(), "");
requirejsBaseUrl = StringUtil.trimEnd(requirejsBaseUrl, "/");
if (requirejsBaseUrl.startsWith("/")) {
requirejsBaseUrl = requirejsBaseUrl.substring(1);
}
} else {
requirejsBaseUrl = "";
}
}
return requirejsBaseUrl;
}
public VirtualFile getBaseUrlPath(boolean parseConfig) {
if (null == requirejsBaseUrl) {
if (parseConfig) {
parseRequirejsConfig();
}
if (null == requirejsBaseUrl) {
return getConfigFileDir();
}
}
return findPathInWebDir(requirejsBaseUrl);
}
protected VirtualFile getConfigFileDir() {
VirtualFile mainJsVirtualFile = findPathInWebDir(settings.configFilePath);
if (null != mainJsVirtualFile) {
return mainJsVirtualFile.getParent();
} else {
return null;
}
}
// private Date lastParse;
public boolean parseRequirejsConfig() {
VirtualFile mainJsVirtualFile = findPathInWebDir(settings.configFilePath);
if (null == mainJsVirtualFile) {
this.showErrorConfigNotification("Config file not found. File " + settings.publicPath + '/' + settings.configFilePath + " not found in project");
LOG.debug("Config not found");
return false;
} else {
PsiFile mainJs = PsiManager.getInstance(project).findFile(mainJsVirtualFile);
if (mainJs instanceof JSFileImpl || mainJs instanceof XmlFileImpl) {
Map<String, VirtualFile> allConfigPaths;
packageConfig.clear();
requireMap.clear();
requirePaths.clear();
if (((PsiFileImpl) mainJs).getTreeElement() == null) {
parseMainJsFile(((PsiFileImpl) mainJs).calcTreeElement());
} else {
parseMainJsFile(((PsiFileImpl) mainJs).getTreeElement());
}
} else {
this.showErrorConfigNotification("Config file wrong format");
LOG.debug("Config file wrong format");
return false;
}
}
return true;
}
public void parseMainJsFile(TreeElement node) {
TreeElement firstChild = node.getFirstChildNode();
if (firstChild != null) {
parseMainJsFile(firstChild);
}
TreeElement nextNode = node.getTreeNext();
if (nextNode != null) {
parseMainJsFile(nextNode);
}
if (node.getElementType() == JSTokenTypes.IDENTIFIER) {
if (node.getText().equals("requirejs") || node.getText().equals("require")) {
TreeElement treeParent = node.getTreeParent();
if (null != treeParent) {
ASTNode firstTreeChild = treeParent.findChildByType(JSElementTypes.OBJECT_LITERAL_EXPRESSION);
TreeElement nextTreeElement = treeParent.getTreeNext();
if (null != firstTreeChild) {
parseRequirejsConfig((TreeElement) firstTreeChild
.getFirstChildNode()
);
} else if (null != nextTreeElement && nextTreeElement.getElementType() == JSTokenTypes.DOT) {
nextTreeElement = nextTreeElement.getTreeNext();
if (null != nextTreeElement && nextTreeElement.getText().equals("config")) {
treeParent = nextTreeElement.getTreeParent();
findAndParseConfig(treeParent);
}
} else {
findAndParseConfig(treeParent);
}
}
}
}
}
protected void findAndParseConfig(TreeElement treeParent) {
TreeElement nextTreeElement;
if (null != treeParent) {
nextTreeElement = treeParent.getTreeNext();
if (null != nextTreeElement) {
ASTNode nextChild = nextTreeElement.findChildByType(JSElementTypes.OBJECT_LITERAL_EXPRESSION);
if (null != nextChild) {
parseRequirejsConfig(
(TreeElement) nextChild.getFirstChildNode()
);
}
}
}
}
public static String dequote(String text) {
return text.replace("\"", "").replace("'", "");
}
public static String dequoteAll(String text) {
return text.replaceAll("\"", "").replaceAll("'", "");
}
public void parseRequirejsConfig(TreeElement node) {
if (null == node) {
return ;
}
try {
if (node.getElementType() == JSElementTypes.PROPERTY) {
TreeElement identifier = (TreeElement) node.findChildByType(JSTokenTypes.IDENTIFIER);
String identifierName = null;
if (null != identifier) {
identifierName = identifier.getText();
} else {
TreeElement identifierString = (TreeElement) node.findChildByType(JSTokenTypes.STRING_LITERAL);
if (null != identifierString) {
identifierName = dequote(identifierString.getText());
}
}
if (null != identifierName) {
if (identifierName.equals("baseUrl")) {
String baseUrl = null;
if (!settings.overrideBaseUrl) {
ASTNode baseUrlNode = node
.findChildByType(JSElementTypes.LITERAL_EXPRESSION);
if (null != baseUrlNode) {
baseUrl = dequote(baseUrlNode.getText());
}
} else {
LOG.info("baseUrl override is enabled, overriding with '" + settings.baseUrl + "'");
baseUrl = settings.baseUrl;
}
if (null != baseUrl) {
LOG.info("Setting baseUrl to '" + baseUrl + "'");
setBaseUrl(baseUrl);
packageConfig.baseUrl = baseUrl;
} else {
LOG.debug("BaseUrl not set");
}
} else if (identifierName.equals("paths")) {
ASTNode pathsNode = node
.findChildByType(JSElementTypes.OBJECT_LITERAL_EXPRESSION);
if (null != pathsNode) {
parseRequireJsPaths(
(TreeElement) pathsNode.getFirstChildNode()
);
}
} else if (identifierName.equals("packages")) {
TreeElement packages = (TreeElement) node.findChildByType(JSElementTypes.ARRAY_LITERAL_EXPRESSION);
LOG.debug("parsing packages");
parsePackages(packages);
LOG.debug("parsing packages done, found " + packageConfig.packages.size() + " packages");
} else if (identifierName.equals("map")) {
TreeElement mapElement = (TreeElement) node.findChildByType(JSElementTypes.OBJECT_LITERAL_EXPRESSION);
parseMapsConfig(mapElement);
}
}
}
} catch (NullPointerException exception) {
LOG.error(exception.getMessage(), exception);
}
TreeElement next = node.getTreeNext();
if (null != next) {
parseRequirejsConfig(next);
}
}
protected void parseMapsConfig(TreeElement mapElement) {
TreeElement firstMapConfigElement = (TreeElement) mapElement.findChildByType(JSElementTypes.PROPERTY);
parseMapConfigElement(firstMapConfigElement);
}
protected void parseMapConfigElement(TreeElement mapConfigElement) {
if (null == mapConfigElement) {
return;
}
if (mapConfigElement.getElementType() == JSElementTypes.PROPERTY) {
String module = getJSPropertyName(mapConfigElement);
TreeElement mapAliasesObject = (TreeElement) mapConfigElement
.findChildByType(JSElementTypes.OBJECT_LITERAL_EXPRESSION);
if (null != mapAliasesObject) {
RequireMapModule requireMapModule = new RequireMapModule();
requireMapModule.module = module;
TreeElement mapAliasProperty = (TreeElement) mapAliasesObject.findChildByType(JSElementTypes.PROPERTY);
parseMapAliasProperty(requireMapModule, mapAliasProperty);
requireMap.addModule(requireMapModule);
}
}
parseMapConfigElement(mapConfigElement.getTreeNext());
}
protected void parseMapAliasProperty(RequireMapModule requireMapModule, TreeElement mapAliasProperty) {
if (null == mapAliasProperty) {
return;
}
if (mapAliasProperty.getElementType() == JSElementTypes.PROPERTY) {
RequirePathAlias alias = new RequirePathAlias();
alias.alias = getJSPropertyName(mapAliasProperty);
alias.path = getJSPropertyLiteralValue(mapAliasProperty);
if (null != alias.alias && alias.path != null) {
requireMapModule.addAlias(alias);
} else {
LOG.debug("Error parse require js path", alias);
}
}
parseMapAliasProperty(requireMapModule, mapAliasProperty.getTreeNext());
}
protected String getJSPropertyName(TreeElement jsProperty) {
TreeElement identifier = (TreeElement) jsProperty.findChildByType(
TokenSet.create(JSTokenTypes.IDENTIFIER, JSTokenTypes.STRING_LITERAL, JSTokenTypes.PUBLIC_KEYWORD)
);
String identifierName = null;
if (null != identifier) {
identifierName = dequote(identifier.getText());
}
return identifierName;
}
private void parsePackages(TreeElement node) {
TokenSet tokenSet = TokenSet.create(
JSElementTypes.OBJECT_LITERAL_EXPRESSION,
JSElementTypes.LITERAL_EXPRESSION);
TreeElement packageNode = (TreeElement) node.findChildByType(tokenSet);
parsePackage(packageNode);
}
private void parsePackage(TreeElement node) {
if (null == node) {
return;
}
if (node.getElementType() == JSElementTypes.OBJECT_LITERAL_EXPRESSION
|| node.getElementType() == JSElementTypes.LITERAL_EXPRESSION
) {
// TODO: Not adding not resolve package
Package p = new Package();
packageConfig.packages.add(p);
if (node.getElementType() == JSElementTypes.OBJECT_LITERAL_EXPRESSION) {
TreeElement prop = (TreeElement) node.findChildByType(JSElementTypes.PROPERTY);
parsePackageObject(prop, p);
} else {
p.name = dequote(node.getText());
}
normalizeParsedPackage(p);
validatePackage(p);
}
TreeElement next = node.getTreeNext();
parsePackage(next);
}
private void normalizeParsedPackage(Package p) {
if (null == p.location) {
p.location = p.name;
}
if (null == p.main) {
p.main = Package.DEFAULT_MAIN;
}
}
private void validatePackage(Package p) {
if (null == getConfigFileDir().findFileByRelativePath(p.location + '/' + p.main + ".js")) {
p.mainExists = false;
} else {
p.mainExists = true;
}
}
private static void parsePackageObject(TreeElement node, Package p) {
if (null == node) {
return;
}
if (node.getElementType() == JSElementTypes.PROPERTY) {
TreeElement identifier = (TreeElement) node.findChildByType(JSTokenTypes.IDENTIFIER);
String identifierName = null;
if (null != identifier) {
identifierName = identifier.getText();
} else {
TreeElement identifierString = (TreeElement) node.findChildByType(JSTokenTypes.STRING_LITERAL);
if (null != identifierString) {
identifierName = dequote(identifierString.getText());
}
}
if (null != identifierName) {
if (identifierName.equals("name")) {
p.name = getJSPropertyLiteralValue(node);
} else if (identifierName.equals("location")) {
p.location = getJSPropertyLiteralValue(node);
} else if (identifierName.equals("main")) {
p.main = getJSPropertyLiteralValue(node);
}
}
}
TreeElement next = node.getTreeNext();
parsePackageObject(next, p);
}
@Nullable
private static String getJSPropertyLiteralValue(TreeElement jsProperty) {
TokenSet availablePropertyValueTokenSet = TokenSet.create(
JSElementTypes.LITERAL_EXPRESSION,
JSElementTypes.BINARY_EXPRESSION,
JSElementTypes.CONDITIONAL_EXPRESSION);
TreeElement jsPropertyValue = (TreeElement) jsProperty.findChildByType(availablePropertyValueTokenSet);
if (null == jsPropertyValue) {
return null;
}
if (jsPropertyValue.getElementType() != JSElementTypes.LITERAL_EXPRESSION) {
jsPropertyValue = (TreeElement) jsPropertyValue.findChildByType(JSElementTypes.LITERAL_EXPRESSION);
if (null == jsPropertyValue) {
return null;
}
}
return dequote(jsPropertyValue.getText());
}
protected void setBaseUrl(String baseUrl) {
if (baseUrl.startsWith("/")) {
baseUrl = baseUrl.substring(1);
}
if (baseUrl.endsWith("/")) {
baseUrl = StringUtil.trimEnd(baseUrl, "/");
}
requirejsBaseUrl = baseUrl;
}
protected void parseRequireJsPaths(TreeElement node) {
if (null == node) {
return ;
}
if (node.getElementType() == JSElementTypes.PROPERTY) {
RequirePathAlias pathAlias = new RequirePathAlias();
pathAlias.alias = getJSPropertyName(node);
pathAlias.path = getJSPropertyLiteralValue(node);
requirePaths.addPath(pathAlias);
}
TreeElement next = node.getTreeNext();
if (null != next) {
parseRequireJsPaths(next);
}
}
public VirtualFile resolvePath(String path) {
VirtualFile rootDirectory;
if (path.startsWith(".")) {
rootDirectory = getBaseUrlPath(false);
} else if (path.startsWith("/")) {
// TODO: Check work on multi modules idea project and empty web path
rootDirectory = getWebDir();
} else {
rootDirectory = getBaseUrlPath(false);
}
if (null != rootDirectory) {
VirtualFile directoryVF = rootDirectory.findFileByRelativePath(path);
if (null != directoryVF) {
return directoryVF;
} else {
VirtualFile fileVF = rootDirectory.findFileByRelativePath(path + ".js");
if (null != fileVF) {
return fileVF;
}
}
}
return null;
}
public PsiElement requireResolve(PsiElement element) {
Path path = new Path(element, this);
return path.resolve();
}
public List<String> getCompletion(PsiElement element) {
List<String> completions = new ArrayList<String>();
String value = element.getText().replace("'", "").replace("\"", "").replace("IntellijIdeaRulezzz ", "");
String valuePath = value;
boolean exclamationMark = value.contains("!");
String plugin = "";
int doubleDotCount = 0;
boolean notEndSlash = false;
String pathOnDots = "";
String dotString = "";
VirtualFile elementFile = element
.getContainingFile()
.getOriginalFile()
.getVirtualFile();
if (exclamationMark) {
String[] exclamationMarkSplit = valuePath.split("!");
plugin = exclamationMarkSplit[0];
if (exclamationMarkSplit.length == 2) {
valuePath = exclamationMarkSplit[1];
} else {
valuePath = "";
}
}
if (exclamationMark) {
for (String moduleName : getModulesNames()) {
completions.add(plugin + '!' + moduleName);
}
} else {
completions.addAll(getModulesNames());
// expand current package
}
PsiDirectory fileDirectory = element
.getContainingFile()
.getOriginalFile()
.getContainingDirectory();
if (null == fileDirectory) {
return completions;
}
String filePath = fileDirectory
.getVirtualFile()
.getPath()
.replace(getWebDir(elementFile).getPath(), "");
if (filePath.startsWith("/")) {
filePath = filePath.substring(1);
}
boolean startSlash = valuePath.startsWith("/");
if (startSlash) {
valuePath = valuePath.substring(1);
}
boolean oneDot = valuePath.startsWith("./");
if (oneDot) {
if (filePath.isEmpty()) {
valuePath = valuePath.substring(2);
} else {
valuePath = valuePath.replaceFirst(".", filePath);
}
}
if (valuePath.startsWith("..")) {
doubleDotCount = FileUtils.getDoubleDotCount(valuePath);
String[] pathsOfPath = filePath.split("/");
if (pathsOfPath.length > 0) {
if (doubleDotCount > 0) {
if (doubleDotCount > pathsOfPath.length || filePath.isEmpty()) {
return new ArrayList<String>();
}
pathOnDots = FileUtils.getNormalizedPath(doubleDotCount, pathsOfPath);
dotString = StringUtil.repeat("../", doubleDotCount);
if (valuePath.endsWith("..")) {
notEndSlash = true;
}
if (valuePath.endsWith("..") || !StringUtil.isEmpty(pathOnDots)) {
dotString = dotString.substring(0, dotString.length() - 1);
}
valuePath = valuePath.replaceFirst(dotString, pathOnDots);
}
}
}
List<String> allFiles = FileUtils.getAllFilesInDirectory(
getWebDir(elementFile),
getWebDir(elementFile).getPath() + '/',
""
);
List<String> aliasFiles = requirePaths.getAllFilesOnPaths();
aliasFiles.addAll(packageConfig.getAllFilesOnPackages());
String requireMapModule = FileUtils.removeExt(element
.getContainingFile()
.getOriginalFile()
.getVirtualFile()
.getPath()
.replace(
getWebDir(elementFile).getPath() + '/',
""
),
".js"
);
completions.addAll(requireMap.getCompletionByModule(requireMapModule));
String valuePathForAlias = valuePath;
if (!oneDot && 0 == doubleDotCount && !startSlash && !getBaseUrl().isEmpty()) {
valuePath = FileUtils.join(getBaseUrl(), valuePath);
}
for (String file : allFiles) {
if (file.startsWith(valuePath)) {
// Prepare file path
if (oneDot) {
if (filePath.isEmpty()) {
file = "./" + file;
} else {
file = file.replaceFirst(filePath, ".");
}
}
if (doubleDotCount > 0) {
if (!StringUtil.isEmpty(valuePath)) {
file = file.replace(pathOnDots, "");
}
if (notEndSlash) {
file = '/' + file;
}
file = dotString + file;
}
if (!oneDot && 0 == doubleDotCount && !startSlash && !getBaseUrl().isEmpty()) {
file = file.substring(getBaseUrl().length() + 1);
}
if (startSlash) {
file = '/' + file;
}
addToCompletion(completions, file, exclamationMark, plugin);
}
}
for (String file : aliasFiles) {
if (file.startsWith(valuePathForAlias)) {
addToCompletion(completions, file, exclamationMark, plugin);
}
}
return completions;
}
private boolean isModuleAccessible(Package pkg, String file, String moduleId) {
return file.endsWith(".js") && !file.equals(moduleId) && !file.equals(pkg.name + '/' + pkg.main + ".js");
// return (restrictAccessToPackage && !file.equals(pkg.name + '/' + pkg.main + ".js")) && file.endsWith(".js") && !file.equals(moduleId);
}
private static void addToCompletion(List<String> completions, String file, boolean exclamationMark, String plugin) {
if (exclamationMark) {
file = FileUtils.removeExt(file, ".js");
completions.add(plugin + '!' + file);
} else if (file.endsWith(".js")) {
completions.add(file.replace(".js", ""));
}
}
// -------------------------------------------------------------------------
// RequireConfigVfsListener
// -------------------------------------------------------------------------
private class RequireConfigVfsListener extends VirtualFileAdapter {
public void contentsChanged(@NotNull VirtualFileEvent event) {
VirtualFile confFile = findPathInWebDir(settings.configFilePath);
if (confFile == null || !confFile.exists() || !event.getFile().equals(confFile)) {
return;
}
LOG.debug("RequireConfigVfsListener contentsChanged");
// RequirejsProjectComponent.this.project.getComponent(RequirejsProjectComponent.class).parseRequirejsConfig();
RequirejsProjectComponent.this.parseRequirejsConfig();
}
}
}